package com.swipemaster.game;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.swipemaster.R;
import com.swipemaster.activities.GameActivity;
import com.swipemaster.common.Coords;
import com.swipemaster.common.Global;
import com.swipemaster.levels.Level;

@SuppressLint("ViewConstructor")
public class GameSurface extends SurfaceView implements SurfaceHolder.Callback
{
	public static Level level;

	private final GameActivity gameActivity;
	private final SurfaceHolder surfaceHolder;
	private Bitmap scaledBackground;

	public GameSurface(GameActivity gameActivity)
	{
		super(gameActivity);

		setFocusable(true);
		this.gameActivity = gameActivity;
		surfaceHolder = getHolder();
		surfaceHolder.addCallback(this);
		setNewLevel();
	}

	public static void setNewLevel()
	{
		level = Global.app.gameMode.getNewLevel();
	}

	@SuppressLint("WrongCall")
	public void drawPreview()
	{
		Canvas canvas = null;
		try
		{
			canvas = surfaceHolder.lockCanvas(null);
			onDraw(canvas);
		}
		finally
		{
			// Do this in a finally so that if an exception is thrown during the above,
			// we don't leave the Surface in an inconsistent state.
			if (canvas != null)
			{
				surfaceHolder.unlockCanvasAndPost(canvas);
			}
		}
	}

	@Override
	public void onDraw(Canvas canvas)
	{
		if (canvas == null)
		{
			return;
		}
		if (scaledBackground != null)
		{
			canvas.drawBitmap(scaledBackground, 0, 0, null);
		}
		level.draw(canvas);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event)
	{
		final int x = (int) event.getX();
		final int y = (int) event.getY();

		// Is event in touch circle?
		if (Coords.distance(level.player.x, level.player.y, x, y) <= Global.app.consts.touchRadius)
		{
			level.player.x = x;
			level.player.y = y;

			// Correct player position, so that it doesn't stick out of the screen.
			if ((level.player.x - level.player.radius) < 0)
			{
				level.player.x = level.player.radius;
			}
			else if ((level.player.x + level.player.radius) >= Global.app.consts.width)
			{
				level.player.x = Global.app.consts.width - level.player.radius;
			}

			if ((level.player.y - level.player.radius) < 0)
			{
				level.player.y = level.player.radius;
			}
			else if ((level.player.y + level.player.radius) >= Global.app.consts.height)
			{
				level.player.y = Global.app.consts.height - level.player.radius;
			}
		}

		return true;
	}

	public void setRunning(boolean isRunning)
	{
		if (isRunning && !Global.app.isDuringGameplay)
		{
			setNewLevel();
		}
		level.setRunning(isRunning);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
	{
		if (scaledBackground == null)
		{
			final Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.my_background_small);
			scaledBackground = Bitmap.createScaledBitmap(background, width, height, true);
		}
		drawPreview();
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
	}

	/** We have to tell thread to shut down & wait for it to finish, or else it might touch the Surface after we return
	 * and explode.
	 * @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.SurfaceHolder) */
	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		boolean retry = true;
		while (retry)
		{
			try
			{
				ThreadManager.join();
				retry = false;
			}
			catch (final InterruptedException e)
			{
				// We will try it again and again...
			}
		}
	}

	public void updateGame()
	{
		final boolean isWinner = level.isWinner();
		if (isWinner || level.isLoser())
		{
			setRunning(false);
			gameActivity.onGameOver(isWinner);
			return;
		}
		level.moveEnemies();
	}

}